﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Trixem.Haved.Web.Classes
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq.Expressions;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    using System.Web.Routing;
    using System.Collections;
    using System.Globalization;

    public static class FormExtensions
    {
        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an Extension Method which allows the user to provide a strongly-typed argument via Expression")]
        public static MvcForm BeginFormA<TController>(this HtmlHelper helper, Expression<Action<TController>> action) where TController : Controller
        {
            return BeginFormA<TController>(helper, action, FormMethod.Post, null);
        }

        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an Extension Method which allows the user to provide a strongly-typed argument via Expression")]
        public static MvcForm BeginFormA<TController>(this HtmlHelper helper, Expression<Action<TController>> action, FormMethod method) where TController : Controller
        {
            return BeginFormA<TController>(helper, action, method, null);
        }

        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an Extension Method which allows the user to provide a strongly-typed argument via Expression")]
        public static MvcForm BeginFormA<TController>(this HtmlHelper helper, Expression<Action<TController>> action, FormMethod method, object htmlAttributes) where TController : Controller
        {
            return BeginFormA<TController>(helper, action, method, new RouteValueDictionary(htmlAttributes));
        }


        private static readonly object _lastFormNumKey = new object();

        private static int IncrementFormCount(IDictionary items)
        {
            object lastFormNum = items[_lastFormNumKey];
            int newFormNum = (lastFormNum != null) ? ((int)lastFormNum) + 1 : 0;
            items[_lastFormNumKey] = newFormNum;
            return newFormNum;
        }
        
        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an Extension Method which allows the user to provide a strongly-typed argument via Expression")]
        public static MvcForm BeginFormA<TController>(this HtmlHelper helper, Expression<Action<TController>> action, FormMethod method, IDictionary<string, object> htmlAttributes) where TController : Controller
        {
            TagBuilder tagBuilder = new TagBuilder("form");
            if (helper.ViewContext.ClientValidationEnabled)
            {
                // forms must have an ID for client validation
                int formNum = IncrementFormCount(helper.ViewContext.HttpContext.Items);
                var formId = String.Format(CultureInfo.InvariantCulture, "form{0}", formNum);
                tagBuilder.GenerateId(formId);
            }
            tagBuilder.MergeAttributes(htmlAttributes);
            string formAction = Microsoft.Web.Mvc.LinkExtensions.BuildUrlFromExpression(helper, action);
            tagBuilder.MergeAttribute("action", formAction);
            tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method));

            helper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
            var theForm = new MvcForm(helper.ViewContext);

            if (helper.ViewContext.ClientValidationEnabled)
            {
                helper.ViewContext.FormContext.FormId = tagBuilder.Attributes["id"];
            }

            return theForm;
        }
    }
}
